//
//  Utils.c
//  Wood
//
//  Created by Wayne on 9/10/14.
//  Copyright (c) 2014 Wayne. All rights reserved.
//

#include <stdlib.h>
#include <string.h>
#include "Arch.h"

Variable *searchVariableFromFrame(Frame *frame, char *name) {
    Variable *variable;
    while (frame != NULL) {
        for (variable = frame->variable; variable != NULL; variable = variable->next) {
            if (strcmp(variable->name, name) == 0) {
                return variable;
            }
        }
        frame = frame->parentFrame;
    }
    return NULL;
}

void addVariableToFrame(Frame *frame, char *name, Value *value) {
    Variable *variable;
    variable = malloc(sizeof(Variable));
    variable->name = name;
    variable->value = *value;
    variable->next = frame->variable;
    frame->variable = variable;
}

FunctionDefinition *searchFunctionDefinitionFromFrame(Frame *frame, char *identifier) {
    FunctionDefinition *function;
    while (frame != NULL) {
        for (function = frame->functionDefinition; function != NULL; function = function->next) {
            if (strcmp(function->name, identifier) == 0) {
                return function;
            }
        }
        frame = frame->parentFrame;
    }
    return NULL;
}

void addFunctionDefinitionToFrame(Frame *frame, char *identifier, ParameterList *parameterList, Block *block) {
    FunctionDefinition *function;
    function = malloc(sizeof(FunctionDefinition));
    function->name = identifier;
    function->type = WdWoodFunctionDefinition;
    function->u.woodFunction.parameter = parameterList;
    function->u.woodFunction.block = block;
    function->next = frame->functionDefinition;
    frame->functionDefinition = function;
}

Frame *createFrame(void) {
    Frame *frame;
    frame = malloc(sizeof(Frame));
    frame->variable = NULL;
    frame->functionDefinition = NULL;
    frame->parentFrame = NULL;
    return frame;
}

void disposeFrame(Frame *frame) {
    while (frame->variable) {
        Variable *temp;
        temp = frame->variable;
        frame->variable = temp->next;
        free(temp);
    }
    while (frame->functionDefinition) {
        FunctionDefinition *temp;
        temp = frame->functionDefinition;
        frame->functionDefinition = temp->next;
        free(temp);
    }
    free(frame);
}